#include "bat_afe.h"
#include "bq_sample.h"
#include <stdio.h>
#include <stdlib.h>
#include "systemdata.h"
#include "delay.h"
#include "wakeup.h"
#include "dvc.h"
#include "temp.h"
static SysRunData_t  *runinfo = NULL;
static SysConfData_t *confinfo = NULL;

static uint32_t cell_valid_bit = 0x00000000;//电芯是否存在标志，每位为1时，表示该电芯有效。总共可支持32串电芯
static float i=0;
static bool dvc11xx_VADF=false;

uint8_t bOTC = 0;//过温标志位
int uiCellVmin,uiCellVmax;
int	uiCellvotage[AFE_MAX_CELL_CNT];
static uint32_t	uiBalMaskFlags=0,uiBalMaskFlags_Prepared=0;


void chgOptionEnable(uint8_t ctrl){//充电功能打开或关闭
	runinfo->funcSwState.bits.SW_CHG_EN	= ctrl;
}

void dsgOptionEnable(uint8_t ctrl){//放电功能打卡或关闭
	runinfo->funcSwState.bits.SW_DSG_EN = ctrl;
}

void afe_prechg_mos_ctrl(bool ctrl){//预充开关控制	
	if(runinfo->sysSwState.bits.SW_PRE == 1 && ctrl == true){
		return;
	}else if(runinfo->sysSwState.bits.SW_PRE == 0 && ctrl == false){
		return;
	}
	PDSG_FETControl(ctrl);
}

void afe_chg_mos_ctrl(bool ctrl){//充电开关控制	
	if(runinfo->sysSwState.bits.SW_CHG == 1 && ctrl == true){
		return;
	}else if(runinfo->sysSwState.bits.SW_CHG == 0 && ctrl == false){
		return;
	}
	CHG_FETControl(ctrl);
}

void afe_chglimit_mos_ctrl(bool ctrl){//充电限流开关控制
	if(runinfo->sysSwState.bits.SW_CHG_LI == 1 && ctrl == true){
		return;
	}else if(runinfo->sysSwState.bits.SW_CHG_LI == 0 && ctrl == false){
		return;
	}
	runinfo->sysSwState.bits.SW_CHG_LI = ctrl;
}

void afe_dsg_mos_ctrl(bool ctrl){//放电开关控制	
	if(confinfo->fctData.otherParmByte.bit.key_check_enable){
		if(get_keywake()==true){
			if(runinfo->sysSwState.bits.SW_DSG == 1 && ctrl == true){
				return;
			}else if(runinfo->sysSwState.bits.SW_DSG == 0 && ctrl == false){
				return;
			}	
			DSG_FETControl(ctrl);
		}else{
			DSG_FETControl(false);
		}
	}else if(confinfo->fctData.otherParmByte.bit.chag_pwr_prchg_enable){//换电用	
		if(runinfo->sysSwState.bits.SW_DSG == 1 && ctrl == true){
			return;
		}else if(runinfo->sysSwState.bits.SW_DSG == 0 && ctrl == false){
			return;
		}	
		DSG_FETControl(ctrl);		
	}
	else{
		if(runinfo->sysSwState.bits.SW_DSG == 1 && ctrl == true){
			return;
		}else if(runinfo->sysSwState.bits.SW_DSG == 0 && ctrl == false){
			return;
		}	
		DSG_FETControl(ctrl);
	}	
}


void afe_balance_enable(uint8_t ctrl){//均衡开关控制	
	if(runinfo->funcSwState.bits.SW_BL_EN == true && ctrl == true){
		return;
	}
	if(runinfo->funcSwState.bits.SW_BL_EN == false && ctrl == false){
		return;
	}
	runinfo->funcSwState.bits.SW_BL_EN = ctrl;
	confinfo->balData.allowCtrl = ctrl;
	saveSysConfData();
	return;
}

void afe_heat_mos_ctrl(uint8_t ctrl){//加热开关控制
	runinfo->sysSwState.bits.SW_HT = ctrl;
	runinfo->funcSwState.bits.SW_HT_EN = ctrl;
	return;
}

void FET_Config(void){
		DSGM_Control(DSGM_CP);//随电荷泵
		DPC_Config(16);//下拉强度16
		BDPT_Config(80);//续流阈值40uV
		ChargePump_Control(CP_10V);//10V
		
		HSFM_Control(0);//允许高边驱动
		
		CHG_FETControl(FET_OPEN);//打开充电
		DSG_FETControl(FET_Close_BFCO);
}


/**
	* @说明	芯片过温保护
	* @参数	过温阈值 uint8_t temp
	* @返回值	
	* @注	
*/
void OverTempProtect(uint8_t temp){
float t;
	t=DVC11XX_Calc_ChipTemp();//获取芯片温度
	
	if(t>=temp)
	bOTC=1;		//过温置位
	else
	bOTC=0;
}

/**
	* @说明	电芯最大最小电压计算
	* @参数	
	* @返回值	
	* @注	
*/
void CalcuVolMaxMin(void){
	s8 cellIndex;
	uint8_t i;
	int cellVoltage;
	for(i=0;i<AFE_MAX_CELL_CNT;i++)
		uiCellvotage[i]=DVC11XX_Calc_VCell(i);//各串电压实际值还原
	uiCellVmin = uiCellVmax = uiCellvotage[0];//初始化
	for(cellIndex=AFE_MAX_CELL_CNT-1;cellIndex>=0;cellIndex--){
		cellVoltage=uiCellvotage[cellIndex];
		if( cellVoltage>uiCellVmax){
			uiCellVmax = cellVoltage;
			if(uiCellVmin==0) 
				uiCellVmin=uiCellVmax;
		}else if(cellVoltage<uiCellVmin && cellVoltage>0){//防0
			uiCellVmin = cellVoltage;
		}
	}
}

//均衡策略，根据均衡开启电压、均衡开启压差和均衡结束压差，计算需要均衡的电芯并返回
void afe_balance_policy(void){
	static uint32_t bal_allow_bits = 0x00000000;//进入均衡标志
	static uint32_t bal_allow_old_bits = 0x00000000;
	static bool enterBalFlag = false;
	if(runinfo->funcSwState.bits.SW_BL_EN == 0 || runinfo->batState == dsgState || runinfo->volProtByte.cellLowVolProt != 0 || runinfo->volProtByte.volProt.bit.afeVolLowProt != 0){//如果均衡开关没有开
		enterBalFlag = false;
	}else{
		if(enterBalFlag == false){
			if(runinfo->batMaxVol >= confinfo->balData.openVol.value && runinfo->maxDiffVol >= confinfo->balData.openDiffVol.value){//最高电压大于均衡开启电压，压差大于开启均衡压差
				enterBalFlag = true;
			}
		}else{//进入均衡的情况下，判断需要均衡的单体，同时判断退出条件
			if(runinfo->batMaxVol < confinfo->balData.openVol.value || runinfo->maxDiffVol < confinfo->balData.endDiffVol.value){
				enterBalFlag = false;
			}
		}
	}
	if(enterBalFlag){		
		for(uint8_t i=0;i<confinfo->fctData.batNum;i++){
			uint16_t diffVol = runinfo->batVol[i] - runinfo->batMinVol;//单体电芯与单体最低电压之差	
			if(runinfo->batVol[i] > confinfo->balData.openVol.value){//单体电压满足均衡开启电压
				if(diffVol > confinfo->balData.openDiffVol.value){
					#ifdef DVC1117
					if(i<10){
						bal_allow_bits |= (1u << i);
					}else{
						bal_allow_bits |=(1u << (2*i-9));
					}
					#endif
					#ifdef DVC1124
						bal_allow_bits |= (1u << i);
					#endif
					runinfo->balState |= (1u << i);					
				}else{	
					#ifdef DVC1117					
					if(i<10){
						bal_allow_bits &= (~(1u<< i));
					}else{
						bal_allow_bits &= (~(1u << (2*i-9)));
					}
					#endif
					#ifdef DVC1124
						bal_allow_bits &= (~(1u<< i));
					#endif
					runinfo->balState &= (~(1u<< i));										
				}		
			}
		}
	}else{
		bal_allow_bits = 0;
		runinfo->balState = 0;
	}
	if(bal_allow_old_bits != bal_allow_bits){
		Balance_Contrl(bal_allow_bits);
	}
	bal_allow_old_bits = bal_allow_bits;	
}

//
void afe_update_balance(void){
	static bool bal_process_start = false;//均衡启动标志
	if(runinfo->funcSwState.bits.SW_BL_EN == 1){//均衡功能打开
		if(bal_process_start == false){//如果未进入均衡流程,判断是否进入均衡流程
			if(runinfo->maxDiffVol >= confinfo->balData.openDiffVol.value){//如果单体最大压差达到均衡开启压差
				for(uint8_t i = 0;i<confinfo->fctData.batNum;i++){
					//如果任意单体电压与单体最低电压的压差达到均衡开启压差，并且此单体电压达到均衡开启电压
					if(((runinfo->batVol[i] - runinfo->batMinVol) >= confinfo->balData.openDiffVol.value) && (runinfo->batVol[i] >= confinfo->balData.openVol.value)){
						bal_process_start = true;//启动均衡流程
						break;
					}
				}
			}
		}
		if(bal_process_start == true){//如果已经进入均衡流程,计算需要均衡的单体，并判断是否退出流程
			static uint64_t period = 0;
			if((period ++)%120 == 0){//执行周期约256mS，每120个周期(约30S)判断一次
				runinfo->balState = 0x00000000;
				for(uint8_t i = 0;i<confinfo->fctData.batNum;i++){
					//如果单体电压达到均衡开启电压，且与单体最低压差低于均衡结束压差
					if((runinfo->batVol[i] >= confinfo->balData.openVol.value) && ((runinfo->batVol[i] - runinfo->batMinVol) >= confinfo->balData.endDiffVol.value)){
						runinfo->balState |= (1u<< i);
					}
				}
				if(runinfo->balState == 0){//如果没有单体需要均衡，则退出均衡流程
					bal_process_start = false;
				}
				Balance_Contrl(runinfo->balState);
			}
		}else{

		}
	}else{//均衡功能关闭
		runinfo->balState = 0x00000000;
		if(bal_process_start == true){//如果已经进入均衡流程
			bal_process_start = false;
			Balance_Contrl(0x00000000);//关闭所有均衡位
		}
	}
}

/**
	* @说明	自动均衡处理
	* @参数	
	* @返回值	
	* @注	
*/
void BalanceProcess(void){
	SysRunData_t  *runInfo = getSysRunData();
	CalcuVolMaxMin();

	uint32_t newBals = 0;
	uint32_t needBals = 0;
	uiBalMaskFlags=(g_AfeRegs.R103_R105.CB[0]<<16)+(g_AfeRegs.R103_R105.CB[1]<<8)+g_AfeRegs.R103_R105.CB[2];//刷新当前均衡位
	if(!bOTC && (uiCellVmin>confinfo->balData.openVol.value)&&(uiCellVmax-uiCellVmin)>=confinfo->balData.openDiffVol.value){//未过温、最低电压高于均衡开启最小电压、压差高于均衡开启阈值
		uint8_t i;
		int cellVoltage=0;
		for(i=0;i<AFE_MAX_CELL_CNT;i++){
			cellVoltage=uiCellvotage[i];
			if( (cellVoltage-uiCellVmin)>=confinfo->balData.openDiffVol.value){
					if(i>9)
					newBals |= (1<<(2*i-9));
					newBals |= (1<<i);	//计算出需要开启均衡的各个位
					needBals |= (1<<i);
			}
		}
	}
	if(runinfo->funcSwState.bits.SW_BL_EN == 1){
		runInfo->balState = needBals;
		if(newBals!=uiBalMaskFlags){ //均衡位变化
			if(newBals==uiBalMaskFlags_Prepared){
				uint8_t i;
				uiBalMaskFlags=uiBalMaskFlags_Prepared;
				Balance_Contrl(uiBalMaskFlags);
				for(i=0;i<AFE_MAX_CELL_CNT;i++){
					if((i>9)&&((uiBalMaskFlags>>(2*i-9)&0x01)==1)){
						printf("CELL %d balance open\r\n",i+1);
					}else{
						
					}
					if((uiBalMaskFlags>>i&0x01)==1){
						printf("CELL %d balance open\r\n",i+1);
					}
				}
			}else{
				uiBalMaskFlags_Prepared=newBals;
			}
		}else{ 
			uiBalMaskFlags_Prepared=uiBalMaskFlags;
		}
	}else{
		runInfo->balState = 0;
	}
		  
}

void afe_poweroff(void){
	dvc11xx_shutdown();
}

void afe_sleep_enter(void){
	dvc11xx_sleep();
	//runinfo->funcSwState.bits.SW_BL_EN = false;
}

void afe_sleep_exit(void){
	dvc11xx_i2c_wakeup();
	//runinfo->funcSwState.bits.SW_BL_EN = true;
}

void afe_set_cellvol_period(DVC11xx_VadcPeriod period){
	dvc11xx_setVadcPeriod(period);
}

static inline void afe_batvol_sort(void){//获取所有单体电压,并计算出单体最高和单体最低及其对应的单体编号
	unsigned char i = 0;
	unsigned int batVolSum = 0;
	unsigned short batMaxVol = 0;
	unsigned char batMaxNum = 0;
	unsigned short batMinVol = 0xffff;
	unsigned char batMinNum = 0;
	for(i=0;i<confinfo->fctData.batNum;i++){//获取所有单体电压,并计算出单体最高和单体最低及其对应的单体编号
		batVolSum += runinfo->batVol[i];
		if(batMaxVol < runinfo->batVol[i]){
			batMaxVol = runinfo->batVol[i];
			batMaxNum  = i+1;
		}
		if(batMinVol > runinfo->batVol[i]){
			batMinVol = runinfo->batVol[i];
			batMinNum  = i+1;
		}
	}
	runinfo->packVol = batVolSum/100;
	if(confinfo->fctData.batNum > 0){
		runinfo->averageVol = batVolSum/confinfo->fctData.batNum;
	}
	runinfo->batMaxVol = batMaxVol;
	runinfo->batMaxNum = batMaxNum;
	runinfo->batMinVol = batMinVol;
	runinfo->batMinNum = batMinNum;
	runinfo->maxDiffVol = batMaxVol - batMinVol;
}






//更新单体电压
//返回值:true、更新完成;false、更新未完成
bool afe_update_cellvol(void){
	if(g_AfeRegs.R1.VADF == 1){//电压转换完成
		g_AfeRegs.R1.VADF = 0;
		for(uint8_t i = 0;i<24;i++){
			if(dvc11xx_read_regs(AFE_ADDR_R((29 + i*2)), 2)){//如果CRC正确
				
			}else{
				printf("afe cell vol update,crc err\n");
			}
		}
		for(uint8_t i=0;i<confinfo->fctData.batNum;i++){
			runinfo->batVol[i] = DVC11XX_Calc_VCell(i); 
//			printf("%04dmV,",runinfo->batVol[i]);
		}
//		printf("\n");
		afe_batvol_sort();
		return true;
	}else{
		return false;
	}
}

void Judge_BatNum(void){
	Set_Bat_Shielding(confinfo->fctData.batNum);
}

void afe_update_status(void){
	//更新故障值
	if(dvc11xx_read_regs(AFE_ADDR_R(0), 2)){//如果CRC正确
		runinfo->curProtByte.bit.shortCurProt |= g_AfeRegs.R0.bitmap.SCD;//获取短路状态
		runinfo->volProtByte.volProt.bit.afeVolHgProt |= g_AfeRegs.R0.bitmap.COV;//获取硬件单体过压状态
		runinfo->volProtByte.volProt.bit.afeVolLowProt |= g_AfeRegs.R0.bitmap.CUV;//获取硬件单体欠压状态
		
		runinfo->curProtByte.bit.chgCur2Prot |= g_AfeRegs.R0.bitmap.OCC1;//获取充电2过流故障
		runinfo->curProtByte.bit.chgCur3Prot |= g_AfeRegs.R0.bitmap.OCC2;//获取充电3过流故障
		runinfo->curProtByte.bit.disCur3Prot |= g_AfeRegs.R0.bitmap.OCD1;//获取放电3过流故障
		runinfo->curProtByte.bit.disCur4Prot |= g_AfeRegs.R0.bitmap.OCD2;//获取放电4过流故障	
		CleanError();//擦除报警
	}else{
		printf("afe status update,crc err\n");
	} 
	//读取mos寄存器值
	if(dvc11xx_read_regs(AFE_ADDR_R(4), 3)){
		runinfo->sysSwState.bits.SW_PRE = g_AfeRegs.R4_6.PDSGF;
		runinfo->sysSwState.bits.SW_CHG = g_AfeRegs.R4_6.CHGF;
		runinfo->sysSwState.bits.SW_DSG = g_AfeRegs.R4_6.DSGF;
	}else{
		printf("afe status mos update,crc err\n");
	}
//	afe_BrokenLineDetect();//断线检测
}

void afe_update_current(void){	 
	//printf("afe update current\n");
	if(dvc11xx_read_regs(AFE_ADDR_R(4), 3)){//如果CRC正确
		runinfo->batRawCur = 0 - DVC11XX_Calc_CurrentWithCC2(CurrentSenseResistance_mR);
		runinfo->batCur = runinfo->batRawCur*confinfo->caliData.curRadio/10000;//通过过滤器CC1的采样值来计算电流 	
//		printf("runinfo->batCur = %d\n",runinfo->batCur);
	}else{
		printf("afe current update,crc err\n");
	}                     
}

void afe_update_bat_temp(void){
	float  vol_mV = GPn_Analog_Input_voltage(GP1)*3.3/1.8;
	runinfo->tempOne = get_temp_by_vol(vol_mV,3435.0);
	vol_mV = GPn_Analog_Input_voltage(GP4)*3.3/1.8;
	runinfo->tempTwo = get_temp_by_vol(vol_mV,3435.0);
}

bool Load_detection(void){
	return hc32_pin_read(LOAD_DET_PIN);
}

void afe_BrokenLineDetect(void){	
	for(uint8_t i=0;i<confinfo->fctData.batNum;i++){
		if(runinfo->batVol[i]==0){
			printf("CELL %d Broken!\r\n",i+1);
//			runinfo->volProtByte.volProt.bit.afeBrokenLine = 1;
		}
	}
}

void afe_OCD1_Config(uint16_t TH,uint16_t DLY){
	OCD1_Config(TH,DLY);
}
void afe_OCD2_Config(uint16_t TH,uint16_t DLY,bool enable){
	OCD2_Config(TH,DLY,1);
}
void afe_OCC1_Config(uint16_t TH,uint16_t DLY){
	OCC1_Config(TH,DLY);
}
void afe_OCC2_Config(uint16_t TH,uint16_t DLY,bool enable){
	OCC2_Config(TH,DLY,1);
//	if(dvc11xx_read_regs(AFE_ADDR_R(95), 1)){//如果CRC正确
//		printf("g_AfeRegs.R95.OCC2E = 0x%02x\n",g_AfeRegs.R95.OCC2E);
//		printf("g_AfeRegs.R95.OCC2T = 0x%02x\n",g_AfeRegs.R95.OCC2T);
//	}
	
}
void afe_OV_Config(uint16_t TH,uint16_t DLY){
	OV_Config(TH,DLY);
}
void afe_UV_Config(uint16_t TH,uint16_t DLY){
	UV_Config(TH,DLY);
}
void afe_SCD_Config(uint16_t TH,uint16_t DLY,bool enable){
	SCD_Config(TH,DLY,1);
}

void Afe_Clear_OCD1(void){
	Clear_OCD1();
}

void Afe_Clear_OCD2(void){
	Clear_OCD2();
}

void Afe_Clear_OCC1(void){
	Clear_OCC1();
}

void Afe_Clear_OCC2(void){
	Clear_OCC2();
}

void Afe_Clear_OV(void){
	Clear_OV();
}

void Afe_Clear_UV(void){
	Clear_UV();
}

void Afe_Clear_SCD(void){
	Clear_SCD();
}

void afe_init(void){
	runinfo = getSysRunData();
	confinfo = getSysConfData();
	DVC11XX_init();
	afe_OV_Config(confinfo->errorData.sov_vol.value,confinfo->errorData.sov_suv_dly_s);
	afe_UV_Config(confinfo->errorData.suv_vol.value,confinfo->errorData.sov_suv_dly_s);
	afe_OCC1_Config(confinfo->errorData.chgOverCurrent2.value,confinfo->errorData.chgOverCurrent2Time);
	afe_OCC2_Config(confinfo->errorData.chgOverCurrent3.value,confinfo->errorData.chgOverCurrent3Time,true);
	afe_OCD1_Config(confinfo->errorData.dsgOverCurrent3.value,confinfo->errorData.dsgOverCurrent3Time);
	afe_OCD2_Config(confinfo->errorData.dsgOverCurrent4.value,confinfo->errorData.dsgOverCurrent4Time.value,true);
	afe_SCD_Config(confinfo->errorData.scdVol.value,confinfo->errorData.scdVolTime.value,1);	
	Clear_OCD1();
	Clear_OCD2();
	Clear_OCC1();
	Clear_OCC2();
	Clear_SCD();
	Clear_OV();
	Clear_UV();

	afe_set_cellvol_period(CC2_1Period);
	runinfo->funcSwState.bits.SW_BL_EN = true;
	runinfo->sysSwState.bits.SW_HT = false;
	runinfo->funcSwState.bits.SW_HT_EN = false;
}